題目敘述
給定一個整數陣列 nums 和一個整數 target,請找出陣列中兩個數字的索引值,使得這兩個數字加總起來剛好等於 target。
解題思路
對於沒接觸過這類問題的人來說,第一直覺可能是使用雙層迴圈暴力解法,嘗試所有可能的數對來找出符合條件的組合:
n = len(nums)
for i in range(n):
    for j in range(i + 1, n):
        if nums[i] + nums[j] == target:
            return [i, j]
然而,這樣的解法時間複雜度為 $O(n^2)$,當陣列長度達到 $10^4$ 時,效率將無法接受。
如何優化至 $O(n)$?
為了在一次遍歷中完成搜尋,我們可以使用一個字典來記錄數字與其對應的索引。這種做法的核心概念是:
i 個數字 num 時,我們需要檢查字典中是否存在 target - num,也就是另一個能湊出 target 的數字。target - num」與當前索引記錄進字典中,等待未來可能的配對。程式碼實作:
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        num_dict = {}  # 用來儲存需要的補數與其對應的索引
        for i, num in enumerate(nums):
            if num in num_dict:
                return [num_dict[num], i]
            else:
                num_dict[target - num] = i
        return []
時間與空間複雜度分析
時間複雜度(Time Complexity):$O(n)$
nums 一次,每次操作包含查找與插入 dict,這些操作平均為 $O(1)$。空間複雜度(Space Complexity):$O(n)$
n 個鍵值對(所有元素的互補數)。版主您好,感謝您對於 Two Sum 問題的深入淺出分享!從暴力解到優化解的思路講解非常清晰,讓我對時間複雜度的重要性有更深刻的體會,尤其 $O(n^2)$ 到 $O(n)$ 的演進更是經典。
對於使用字典(或雜湊表)的 $O(n)$ 解法,您的程式碼實作非常精簡且有效。我在閱讀時,對於字典 num_dict 中鍵值對的儲存邏輯,例如:「將當前的『互補數 target - num』與當前索引記錄進字典中,等待未來可能的配對」,這段說明與程式碼 num_dict[target - num] = i 對應得很好。不過,為了讓讀者更直觀理解,或許也可以補充說明當我們檢查 if num in num_dict: 時,這個 num 其實就是我們預期會遇到的「補數」本身,而 num_dict[num] 則儲存著它所需配對數字的索引。這樣或許能讓這個經典的邏輯轉折點更一目瞭然!
再次感謝您的分享,寫得非常棒!
也歡迎版主有空參考我的系列文「南桃AI重生記」:
https://ithelp.ithome.com.tw/users/20046160/ironman/8311